﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace Antioch.Base
{
    public class PlayerControllerBase : Jemgine.Engine.EntityComponent
    {
        public virtual void Update(bool JumpPressed, bool UsePressed, bool FirePressed, Vector2 NavStick, Vector2 AimStick,
            Vector2 MouseAim) { }
    }

	[Jemgine.Engine.Category("Controllers"), Jemgine.Engine.Component]
	public class PlayerController : PlayerControllerBase
	{
        [Jemgine.Engine.Tweakable("AirControl")]
		public float HorizontalAirControl { get; set; }

        [Jemgine.Engine.Tweakable("RunForce")]
		public float RunForce { get; set; }

		public float JumpForce { get; set; }

        [ContentSerializerIgnore]
        PlayerStates.StateMachine Machine;

        [ContentSerializerIgnore]
        public Weapon SelectedWeapon { get; set; }

        public PlayerController()
        {
            AddInput("Hurt", null);
            AddReference("AnimatedSkeleton", typeof(Jemgine.Engine.AnimatedSkeleton));
            AddReference("Weapon Bone", typeof(Jemgine.Data.Bone));
        }

        public override void FireTerminal(int InputID, Jemgine.Data.ScriptPayload Payload)
        {
            if (InputID == 0)
                Machine.Input.Hurt = true;
        }
       
        public override void _Initialize(ContentManager Content)
        {
            Machine = new PlayerStates.StateMachine();
            Machine.PhysicsComponent = Me.GetComponent<Jemgine.Engine.ActorPhysics>();
            Machine.DrawComponent = ReferenceTerminals[0].Target as Jemgine.Engine.AnimatedSkeleton;
            Machine.NavigationModule = Sim.GetModule<PlayerNavigationModule>();
            Machine.PhysicsModule = Sim.GetModule<Jemgine.Engine.PhysicsModule>();
            Machine.PlayerEntity = Me;
            Machine.Controller = this;

            Machine.Settings.JumpForce = JumpForce;
            Machine.Settings.RunForce = RunForce;
            Machine.Settings.HorizontalAirControl = HorizontalAirControl;

            Machine.Input.JumpPressed = false;
            Machine.Input.NavigationStick = Vector2.Zero;
            Machine.Input.Hurt = false;

            base._Initialize(Content);

            SelectedWeapon = new Pistol(Content);
        }

        public override void Update(bool JumpPressed, bool UsePressed, bool FirePressed, Vector2 NavStick, Vector2 AimStick,
            Vector2 MouseAim)
        {
            if (Machine == null) return;

            Machine.Input.NavigationStick = NavStick;
            Machine.Input.RawAimStick = AimStick;
            Machine.Input.MouseAim = MouseAim;

            Vector2 Aim = AimStick;
            if (Jemgine.Math.Vector.AlmostZero(Aim))
                Aim = new Vector2(Me.Facing == Jemgine.Data.Facings.Right ? 1 : -1, 0);

            Aim.Normalize();
            Aim = Vector2.Transform(Aim, Matrix.CreateRotationZ(Me.Angle));

            Machine.Input.WorldAimStick = Aim;

            Machine.Input.JumpPressed = JumpPressed;
            Machine.Input.UsePressed = UsePressed;
            Machine.Input.FirePressed = FirePressed;
            if (Machine.CurrentState == null) Machine.Transition(typeof(PlayerStates.Stand));
            Machine.Update();

            Machine.Input.NavigationStick = Vector2.Zero;
            Machine.Input.Hurt = false;

            if (Machine.Output.CanFire && SelectedWeapon != null)
                SelectedWeapon.Update(Me, FirePressed, Aim);
        }

        //void Jemgine.Engine.DrawableComponent.Draw(Jemgine.Renderer.RenderContext Renderer)
        //{
        //    Renderer.DrawLine(Vector2.Zero, 5 * Machine.Input.WorldAimStick, 0.2f);
        //    if (SelectedWeapon != null) SelectedWeapon.Draw(Me, Machine, Renderer);
        //}
    }
}
